package org.jeecg.modules.demo.meituan;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.SneakyThrows;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.demo.api.UpmsHelloApi;
import org.jeecg.modules.demo.entity.Dept;
import org.jeecg.modules.demo.mall.api.MallHelloApi;
import org.jeecg.modules.demo.weixin.dto.PayDto;
import org.jeecg.modules.demo.weixin.dto.YxMeituanExamineDto;
import org.jeecg.modules.demo.weixin.entity.*;
import org.jeecg.modules.demo.weixin.meituan.dto.ConsumeDto;
import org.jeecg.modules.demo.weixin.meituan.util.AppConstants;
import org.jeecg.modules.demo.weixin.meituan.util.MeiTuanUtil;
import org.jeecg.modules.demo.weixin.meituan.util.RequestUtil;
import org.jeecg.modules.demo.weixin.meituan.util.SignUtil;
import org.jeecg.modules.demo.weixin.meituan.vo.GroupInfoVo;
import org.jeecg.modules.demo.weixin.payorder.service.IPayOrderService;
import org.jeecg.modules.demo.weixin.smtdev.service.ISmtDevService;
import org.jeecg.modules.demo.weixin.smtmeituanlink.service.ISmtMeituanLinkService;
import org.jeecg.modules.demo.weixin.smtmeituantuangou.service.ISmtMeituanTuangouService;
import org.jeecg.modules.demo.weixin.smtyuyuelist.service.ISmtYuyueListService;
import org.jeecg.modules.demo.weixin.smtyuyueuser.mapper.SmtYuyueUserMapper;
import org.jeecg.modules.demo.weixin.smtyuyueuser.service.ISmtYuyueUserService;
import org.jeecg.modules.demo.weixin.util.MD5Util;
import org.jeecg.modules.demo.weixin.yxmeituanverfication.service.IYxMeituanVerficationService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/weixin/meituan")
public class MeiTuanApiController {
    @Autowired
    private ISmtMeituanLinkService smtMeituanLinkService;
    @Autowired
    private ISmtMeituanTuangouService smtMeituanTuangouService;
    @Autowired
    private IPayOrderService payOrderService;
    @Autowired
    private UpmsHelloApi upmsHelloApi;
    @Autowired
    private MallHelloApi mallHelloApi;
    @Autowired
    private ISmtYuyueListService smtYuyueListService;
    @Autowired
    private IYxMeituanVerficationService yxMeituanVerficationService;

    @Autowired
    private ISmtYuyueUserService yuyueUserService;

    @Autowired
    private SmtYuyueUserMapper yuyueUserMapper;
    @Autowired
    private ISmtDevService smtDevService;


    /**
     * 根据手机号查询可用团购券
     *
     * @return
     */
    @SneakyThrows
    @GetMapping("/getByPhone")
    public Object getByPhone(@RequestParam("mobile") String mobile, String merId) {
        //根据店铺id查询session（token）
        SmtMeituanLink meituanLink = smtMeituanLinkService.getOne(new QueryWrapper<SmtMeituanLink>().lambda().eq(SmtMeituanLink::getMerchantId, Integer.valueOf(merId)));
        if (ObjectUtils.isEmpty(meituanLink)) {
            return Result.error("根据手机号查询可用团购券 未获取到session值!");
        }

        //先获取店铺下所有团购信息（获取团购详情）
        JSONObject groupBuyingInfo = MeiTuanUtil.getGroupBuyingInfo(meituanLink.getOpenShopUuid(), meituanLink.getSessionCode());
        if (!groupBuyingInfo.get("code").equals(200)) {
            return Result.error(606, groupBuyingInfo.getString("msg"));
        }

        List<GroupInfoVo> infoVoList = new ArrayList<>();

        //循环获取每一个团购商品的套餐id和团购id 进行获取团购券码
        JSONArray data = groupBuyingInfo.getJSONArray("data");
        for (int i = 0; i < data.size(); i++) {

            Map<String, String> requestParam = new HashMap<>();
            requestParam.put("app_key", AppConstants.appKey);
            requestParam.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            requestParam.put("format", "json");
            requestParam.put("v", "1");
            requestParam.put("sign_method", "MD5");
            requestParam.put("session", meituanLink.getSessionCode());
            requestParam.put("open_shop_uuid", meituanLink.getOpenShopUuid());
            requestParam.put("mobile", mobile);
            requestParam.put("deal_group_id", data.getJSONObject(i).getString("dealgroup_id"));
            requestParam.put("deal_id", data.getJSONObject(i).getString("deal_id"));
            requestParam.put("offset", "0");
            requestParam.put("limit", "10");
            requestParam.put("platform", "2");//平台，1点评，2美团
            //验证签名，详情见签名生成说明文档
            requestParam.put("sign", SignUtil.signTopRequest(requestParam, AppConstants.APP_SECRET, AppConstants.SIGN_METHOD_MD5));

            //Map转URL的参数串
            String s = RequestUtil.mapToGetParam(requestParam);

            //发起get请求
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpGet get = new HttpGet(AppConstants.phoneUrl + s);
            CloseableHttpResponse responses = null;
            responses = httpClient.execute(get);
            String contents = EntityUtils.toString(responses.getEntity());
            JSONObject jsonObject = JSONObject.parseObject(contents);
            System.out.println(jsonObject);
            if (jsonObject.get("code").equals(200)) {
                //同一手机号下会有多个券码 循环将每一个券码对应的商品信息返回
                JSONArray serialNumber = jsonObject.getJSONArray("data");
                for (int j = 0; j < serialNumber.size(); j++) {
                    GroupInfoVo groupInfoVo = new GroupInfoVo();
                    groupInfoVo.setDealId(data.getJSONObject(i).getLong("deal_id"));
                    groupInfoVo.setDealGroupId(data.getJSONObject(i).getLong("dealgroup_id"));
                    groupInfoVo.setBeginDate(data.getJSONObject(i).getString("begin_date"));
                    groupInfoVo.setEndDate(data.getJSONObject(i).getString("end_date"));
                    groupInfoVo.setTitle(data.getJSONObject(i).getString("title"));
                    groupInfoVo.setPrice(data.getJSONObject(i).getDouble("price"));
                    groupInfoVo.setReceiptBeginDate(data.getJSONObject(i).getString("receipt_begin_date"));
                    groupInfoVo.setReceiptEndDate(data.getJSONObject(i).getString("receipt_end_date"));
                    groupInfoVo.setSaleStatus(data.getJSONObject(i).getInteger("sale_status"));
                    groupInfoVo.setDealType(data.getJSONObject(i).getString("deal_type"));
                    groupInfoVo.setSerialNumber(serialNumber.getJSONObject(j).getString("serial_number"));
                    infoVoList.add(groupInfoVo);
                }

            }

        }
        return data;
    }

    /**
     * 美团验券接口
     */
    @PostMapping("/consume")
    @SneakyThrows
    public Result consume(@RequestBody ConsumeDto req) {
        //小程序商家
        LambdaQueryWrapper<SmtDev> smtDevLambdaQueryWrapper = new LambdaQueryWrapper<>();
        smtDevLambdaQueryWrapper.eq(SmtDev::getMerchantId, req.getMerId());
        List<SmtDev> smtDevList = smtDevService.list(smtDevLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(smtDevList)){
            Result.error("需要绑定小程序设备");
        }
        List<String> devList = smtDevList.stream().map(SmtDev::getDevCode).collect(Collectors.toList());

        //根据店铺id查询session（token）
        List<SmtMeituanLink> smtMeituanLink=new   ArrayList<>();
        //根据店铺id查询session（token）
        devList.forEach(ev->{
            List<SmtMeituanLink> one = smtMeituanLinkService.list(new QueryWrapper<SmtMeituanLink>().lambda().like(SmtMeituanLink::getDevCode, ev));
            if (!CollectionUtils.isEmpty(one)){
                smtMeituanLink.add(one.get(0));
            }
        });
        if (CollectionUtils.isEmpty(smtMeituanLink)) {
            return Result.error("美团验券接口 未获取到session值!");
        }
        //调用门店接口  查询门店的poiId
        Dept dept = upmsHelloApi.queryByDept(Long.valueOf(Long.valueOf(req.getMerId())));
        if (dept == null) {
            return Result.error(606, "门店不存在");
        }
        //预约表的修改
        SmtYuyueList yuyueList = smtYuyueListService.getById(req.getYuyueId());
        if (yuyueList == null) {
            return Result.error(606, "预约不存在");
        }
        //核销结束查询预约场次  看是都有冲突
        if ((yuyueList.getCount() - yuyueList.getNum()) < req.getNum()) {
            return Result.error(606, "当前排期人数已满，请选择其他排期！");
        }
        yuyueList.setNum(yuyueList.getNum() + req.getNum());

        YxMeituanVerfication consume = MeiTuanUtil.consume(smtMeituanLink.get(0).getSessionCode(), smtMeituanLink.get(0).getOpenShopUuid(), req.getCode());
        if (consume == null) {
            return Result.error(606, "核销失败");
        }
        //添加美团关联订单记录
        yxMeituanVerficationService.save(consume);
        //创建订单
        PayOrder payOrder = new PayOrder();
        BeanUtils.copyProperties(req, payOrder);
        //抖音订单本来金额 分  需要转换
        payOrder.setMerchantId(req.getMerId());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String orderNo = MD5Util.encryptMd5(simpleDateFormat.format(new Date()) + RandomUtil.randomNumbers(10));
        payOrder.setOrderNo(orderNo);
        payOrder.setTrkName(consume.getDealTitle());
        payOrder.setCount(req.getNum());
        payOrder.setPayPrice(consume.getAmount());
        payOrder.setActualPrice(payOrder.getPayPrice());
        payOrder.setTotalPrice(consume.getDealPrice());
        payOrder.setPayStatus("2");
        payOrder.setPayMode("4");
        payOrder.setOrderType(5);
        payOrder.setPayTime(new Date());
        payOrder.setMtCode(consume.getReceiptCode());
        payOrder.setMerchantName(dept.getName());
        payOrder.setPayType("Meituan");
        payOrder.setSourceType(1);
        payOrderService.save(payOrder);
        PayDto payDto = new PayDto();
        payDto.setYuYueId(req.getYuyueId());
        payDto.setOrderCouponNo(payOrder.getOrderNo());
        payDto.setOrd(yuyueList.getOrd());
        payDto.setCount(req.getNum());
        payDto.setQrCode(yuyueList.getQrCode());
        //修改预约场次已有人数
        smtYuyueListService.updateById(yuyueList);
        yuyueUserService.saveUser(payDto);
        return Result.ok("核销成功");
    }

    /**
     * 美团核销校验接口
     */
    @PostMapping("/examine")
    @SneakyThrows
    public Result examine(@RequestBody ConsumeDto consumeDto) {
        LambdaQueryWrapper<SmtDev> smtDevLambdaQueryWrapper = new LambdaQueryWrapper<>();
        smtDevLambdaQueryWrapper.eq(SmtDev::getMerchantId, consumeDto.getMerId());
        List<SmtDev> smtDevList = smtDevService.list(smtDevLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(smtDevList)){
            Result.error("需要绑定小程序设备");
        }
        List<String> devList = smtDevList.stream().map(SmtDev::getDevCode).collect(Collectors.toList());
        List<SmtMeituanLink> smtMeituanLink=new   ArrayList<>();
        //根据店铺id查询session（token）
        devList.forEach(ev->{
            List<SmtMeituanLink> one = smtMeituanLinkService.list(new QueryWrapper<SmtMeituanLink>().lambda().like(SmtMeituanLink::getDevCode, ev));
            if (!CollectionUtils.isEmpty(one)){
                smtMeituanLink.add(one.get(0));
            }
        });
        if (CollectionUtils.isEmpty(smtMeituanLink)) {
            return Result.error("美团验券接口 未获取到session值!");
        }
        YxMeituanExamineDto examine = MeiTuanUtil.examine(smtMeituanLink.get(0).getSessionCode(), smtMeituanLink.get(0).getOpenShopUuid(), consumeDto.getCode());
        if (examine == null) {
            return Result.error(606, "核销验证失败，请审核信息");
        }
        //根据返回的数据查看对应套餐
        LambdaQueryWrapper<SmtMeituanTuangou> queryWrapperTuangou = new LambdaQueryWrapper<>();
        queryWrapperTuangou.eq(SmtMeituanTuangou::getDealgroupId, String.valueOf(examine.getDealgroupId()));
        queryWrapperTuangou.eq(SmtMeituanTuangou::getDealId, String.valueOf(examine.getDealId()));
//        queryWrapperTuangou.eq(SmtMeituanTuangou::getUserId, Integer.valueOf(consumeDto.getMerId()));
        SmtMeituanTuangou meituanTuangou = smtMeituanTuangouService.getOne(queryWrapperTuangou);
        if (meituanTuangou == null) {
            return Result.error(606, "没有对应套餐");
        }
        //判断美团表是否有数据没有添加  有的话进行返回
        examine.setStock(meituanTuangou.getCount());
        return Result.OK(examine);
    }

    /**
     * 美团核销校验接口，注意（十分钟后无法撤销，同一订单48小时内只能撤销5次）
     */
    @PostMapping("/chexiao")
    @SneakyThrows
    public Object chexiao(@RequestBody ConsumeDto consumeDto) {
        //获取订单编号
        LambdaQueryWrapper<PayOrder> payOrderLambdaQueryWrapper = new LambdaQueryWrapper<PayOrder>();
        payOrderLambdaQueryWrapper.eq(PayOrder::getOrderNo, consumeDto.getOrderNo());
        payOrderLambdaQueryWrapper.eq(PayOrder::getPayStatus, "2");
        PayOrder payOrder = payOrderService.getOne(payOrderLambdaQueryWrapper);
        if (payOrder == null) {
            Result.error("没有美团团购核销订单信息");
        }
        LambdaQueryWrapper<YxMeituanVerfication> verficationWrapper = new LambdaQueryWrapper<YxMeituanVerfication>();
        verficationWrapper.eq(YxMeituanVerfication::getReceiptCode, payOrder.getMtCode());
        YxMeituanVerfication meituanCode = yxMeituanVerficationService.getOne(verficationWrapper);
        if (meituanCode == null) {
            Result.error("没有核销记录信息");
        }
        //根据店铺id查询session（token）
        SmtMeituanLink smtMeituanLink = smtMeituanLinkService.getOne(new QueryWrapper<SmtMeituanLink>().lambda().eq(SmtMeituanLink::getMerchantId, Integer.valueOf(consumeDto.getMerId())));
        if (ObjectUtils.isEmpty(smtMeituanLink)) {
            return Result.error("美团验券接口 未获取到session值!");
        }
        //撤销
        Object chexiao = MeiTuanUtil.chexiao(smtMeituanLink.getSessionCode(), smtMeituanLink.getOpenShopUuid(), meituanCode.getReceiptCode(), String.valueOf(meituanCode.getDealId()));
        if (chexiao == null) {
            return Result.error(606, "核销验证失败，请审核信息");
        }
        payOrder.setPayStatus("3");
        if (payOrder.getOrderType() == 3) {
            //根据订单选择的排期id查询排期
            SmtYuyueList yuyueList = smtYuyueListService.getById(payOrder.getYuyueId());
            //减掉占位
            Integer num = yuyueList.getNum() - payOrder.getCount();
            yuyueList.setNum(num);
            smtYuyueListService.updateById(yuyueList);
            //根据预约id查询对应的玩家并修改状态
            yuyueUserMapper.updateStatus(payOrder.getYuyueId(), payOrder.getCount(),null, payOrder.getOrderNo());
        }
        return Result.ok("撤销成功");
    }




    @PostMapping("/chexiaotuangeou")
    @SneakyThrows
    public Object chexiaotuangeou(@RequestBody ConsumeDto consumeDto) {

        //撤销
        Object chexiao = MeiTuanUtil.chexiao(consumeDto.getMerId(), consumeDto.getYuyueId(), consumeDto.getCode(), String.valueOf(consumeDto.getDealId()));
        if (chexiao == null) {
            return Result.error(606, "核销验证失败，请审核信息");
        }
        return Result.ok("撤销成功");
    }

}
